import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from scipy.stats import pearsonr
from sklearn.preprocessing import MinMaxScaler
import matplotlib

matplotlib.use('TkAgg')  # 或者尝试 'Qt5Agg', 'Agg' 等
import matplotlib.pyplot as plt

import matplotlib

# 设置全局字体，确保 'SimHei' 或其他你安装的中文字体名称正确
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
# 解决负号'-'显示为方块的问题
matplotlib.rcParams['axes.unicode_minus'] = False


# 手动实现一致性相关系数计算函数
def concordance_correlation_coefficient(y_true, y_pred):
    mean_true = np.mean(y_true)
    mean_pred = np.mean(y_pred)
    var_true = np.var(y_true)
    var_pred = np.var(y_pred)
    covar = np.cov(y_true, y_pred)[0, 1]

    ccc = (2 * covar) / (var_true + var_pred + (mean_true - mean_pred) ** 2)
    return ccc


def do_once():
    # 数据加载
    data = pd.read_excel(r'C:\Users\32407\Desktop\soil-terrain attributes.xlsx')
    X = data.drop('SD', axis=1).values
    y = data['SD'].values

    # 数据归一化
    scaler = MinMaxScaler()
    X = scaler.fit_transform(X)

    # 数据划分
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=None)

    # 定义随机森林回归模型
    rf = RandomForestRegressor(n_estimators=500, random_state=42)

    # 训练模型
    rf.fit(X_train, y_train)

    # 获取特征重要性
    feature_importances = rf.feature_importances_

    # 预测
    pre_test = rf.predict(X_test)

    # 测试误差
    r_test, _ = pearsonr(y_test, pre_test)
    r2_test = r_test ** 2
    rmse_test = np.sqrt(np.mean((y_test - pre_test) ** 2))
    mae_test = np.mean(np.abs(y_test - pre_test))
    CCC_test = concordance_correlation_coefficient(y_test, pre_test)

    cor_RF = np.array([r2_test, CCC_test, rmse_test, mae_test])
    return cor_RF, feature_importances


# 重复结果 1000 次
all_feature_importances = []
repeat1000 = []
for _ in range(10):
    cor_RF, feature_importances = do_once()
    repeat1000.append(cor_RF)
    all_feature_importances.append(feature_importances)

repeat1000 = np.array(repeat1000)
all_feature_importances = np.array(all_feature_importances)
mean_feature_importances = np.mean(all_feature_importances, axis=0)

data = pd.read_excel(r'C:\Users\32407\Desktop\soil-terrain attributes.xlsx')
print(data.columns)
feature_names = data.drop('SD', axis=1).columns
sorted_indices = np.argsort(mean_feature_importances)[::-1]
sorted_feature_importances = mean_feature_importances[sorted_indices]
sorted_feature_names = feature_names[sorted_indices]

# 打印特征重要性
print("特征重要性排序:")
for feature, importance in zip(sorted_feature_names, sorted_feature_importances):
    print(f"{feature}: {importance}")

# 绘制特征重要性柱状图
plt.bar(range(len(sorted_feature_names)), sorted_feature_importances)
plt.xticks(range(len(sorted_feature_names)), sorted_feature_names, rotation=45)
plt.xlabel('特征名称')
plt.ylabel('特征重要性')
plt.title('随机森林特征重要性')
plt.show()

cor = np.mean(repeat1000, axis=0)
cor_matrix = pd.DataFrame(cor.reshape(-1, 1), index=['r2_test', 'CCC_test', 'rmse_test', 'mae_test'],
                          columns=['cor_RF'])

# 保存结果到 Excel 文件
cor_df = pd.DataFrame(repeat1000, columns=['r2_test', 'CCC_test', 'rmse_test', 'mae_test'])
cor_df.to_excel('rf-all-all-128.xlsx', index=False)
cor_matrix.to_excel('rf-all-128.xlsx')



